// web_app.js
const Koa = require("koa");
const Router = require("@koa/router");
const serve = require("koa-static");
const path = require("path");
const fs = require("fs");
const { koaBody } = require("koa-body");
const { LocalQASystem } = require("./ask");

const app = new Koa();
const router = new Router();

// 全局错误处理中间件
app.use(async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    console.error("服务器错误:", err);
    ctx.status = err.status || 500;
    ctx.body = { error: err.message || "Internal Server Error" };
  }
});

// 配置 koa-body 用于文件上传和请求体解析
app.use(
  koaBody({
    multipart: true,
    formidable: {
      maxFileSize: 16 * 1024 * 1024, // 16MB
      multiples: false,
      keepExtensions: true,
    },
    json: true,
    text: true,
  })
);

// 提供静态文件服务
app.use(serve(path.join(__dirname, "templates")));

// 初始化问答系统
const qaSystem = new LocalQASystem();
let systemInitialized = false;
console.log("正在初始化问答系统...");

qaSystem.initSystem().then((success) => {
  systemInitialized = success;
  if (!success) {
    console.log("系统初始化失败！");
  } else {
    console.log("系统初始化成功！");
  }
});

// 路由处理
router.get("/", async (ctx) => {
  try {
    ctx.type = "html";
    ctx.body = fs.readFileSync(
      path.join(__dirname, "templates", "index.html"),
      "utf8"
    );
  } catch (error) {
    ctx.status = 500;
    ctx.body = { error: "无法加载页面" };
  }
});

router.post("/ask", async (ctx) => {
  try {
    // 检查系统是否已初始化
    if (!systemInitialized) {
      ctx.status = 500;
      ctx.body = { error: "系统正在初始化中，请稍后再试" };
      return;
    }

    const { question } = ctx.request.body;

    if (!question || question.trim() === "") {
      ctx.status = 400;
      ctx.body = { error: "问题不能为空" };
      return;
    }

    const answer = await qaSystem.askQuestion(question.trim());
    ctx.body = { answer };
  } catch (error) {
    console.error("问答处理错误:", error);
    ctx.status = 500;
    ctx.body = { error: `回答问题时出现错误: ${error.message}` };
  }
});

router.post("/upload", async (ctx) => {
  try {
    console.log("收到上传请求");

    if (!ctx.request.files || !ctx.request.files.file) {
      ctx.status = 400;
      ctx.body = { error: "没有文件被上传" };
      return;
    }

    const file = ctx.request.files.file;
    console.log("上传的文件信息:", file);

    // 检查文件类型
    const filename = file.name || file.originalFilename || file.filename;
    if (!filename) {
      ctx.status = 400;
      ctx.body = { error: "文件名无效" };
      return;
    }

    if (!filename.toLowerCase().endsWith(".txt")) {
      ctx.status = 400;
      ctx.body = { error: "只支持txt文件" };
      return;
    }

    const dataDir = path.join(__dirname, "data");
    if (!fs.existsSync(dataDir)) {
      fs.mkdirSync(dataDir, { recursive: true });
    }

    // 保存文件到 data 目录
    const filePath = path.join(dataDir, filename);

    // 使用流的方式复制文件，更可靠
    const readStream = fs.createReadStream(file.path || file.filepath);
    const writeStream = fs.createWriteStream(filePath);

    await new Promise((resolve, reject) => {
      readStream.pipe(writeStream);
      writeStream.on("finish", resolve);
      writeStream.on("error", reject);
      readStream.on("error", reject);
    });

    console.log(`文件 ${filename} 上传成功，保存到: ${filePath}`);

    // 删除临时文件
    try {
      const tempPath = file.path || file.filepath;
      if (tempPath && fs.existsSync(tempPath)) {
        fs.unlinkSync(tempPath);
      }
    } catch (err) {
      console.warn("删除临时文件警告:", err.message);
    }

    // 验证文件是否保存成功
    if (!fs.existsSync(filePath)) {
      ctx.status = 500;
      ctx.body = { error: "文件保存失败" };
      return;
    }

    // 重新初始化系统以包含新文档
    console.log(`正在重新初始化系统以包含新文档: ${filename}`);
    systemInitialized = false; // 设置为未初始化状态
    const success = await qaSystem.initSystem();
    systemInitialized = success; // 更新初始化状态

    if (success) {
      ctx.body = { message: `文件 ${filename} 上传成功并已添加到知识库` };
    } else {
      // 如果初始化失败，删除刚上传的文件
      try {
        if (fs.existsSync(filePath)) {
          fs.unlinkSync(filePath);
        }
      } catch (err) {
        console.error("清理文件失败:", err);
      }
      ctx.status = 500;
      ctx.body = { error: "文件上传成功，但系统重新初始化失败" };
    }
  } catch (error) {
    console.error("上传处理错误:", error);
    ctx.status = 500;
    ctx.body = { error: `上传失败: ${error.message}` };
  }
});

router.get("/database/info", async (ctx) => {
  try {
    // 检查系统是否已初始化
    if (!systemInitialized) {
      ctx.status = 500;
      ctx.body = { error: "系统正在初始化中，请稍后再试" };
      return;
    }

    // 获取分页参数
    const page = parseInt(ctx.query.page) || 1;
    const perPage = parseInt(ctx.query.per_page) || 5;

    const info = await qaSystem.getDatabaseInfo(page, perPage);
    ctx.body = info;
  } catch (error) {
    console.error("数据库信息获取错误:", error);
    ctx.status = 500;
    ctx.body = { error: error.message };
  }
});

router.get("/system/status", async (ctx) => {
  try {
    const status = qaSystem.getSystemStatus();
    status.initialized = systemInitialized;
    ctx.body = status;
  } catch (error) {
    console.error("系统状态获取错误:", error);
    ctx.status = 500;
    ctx.body = { error: error.message };
  }
});

// 添加一个手动重新初始化系统的接口
router.post("/reinit", async (ctx) => {
  try {
    systemInitialized = false;
    const success = await qaSystem.initSystem();
    systemInitialized = success;

    if (success) {
      ctx.body = { message: "系统重新初始化成功" };
    } else {
      ctx.status = 500;
      ctx.body = { error: "系统重新初始化失败" };
    }
  } catch (error) {
    console.error("系统重新初始化错误:", error);
    systemInitialized = false;
    ctx.status = 500;
    ctx.body = { error: error.message };
  }
});

// 使用路由
app.use(router.routes());
app.use(router.allowedMethods());

const port = process.env.PORT || 5000;
app.listen(port, "0.0.0.0", () => {
  console.log(`服务器运行在 http://0.0.0.0:${port}`);
  console.log(`请确保 ChromaDB 服务器已在 http://localhost:8000 运行`);
});
